module top(
    input wire clk,       // System clock
    input wire rst_n,   // Active low reset
    input wire LR,    // Left/Right channel select
    input wire i2s_data,    // I2S serial data input
    output wire i2s_bclk,   // I2S bit clock
    output wire i2s_lrclk,  // I2S left-right clock

    output wire out_i2s_data,   // Filtered I2S data output
    output wire out_i2s_data_vld,   // Filtered I2S data valid signal
    output wire out_i2s_bclk,   // Filtered I2S bit clock
    output wire out_i2s_lrclk   // Filtered I2S left-right clock

);
    // Instantiate i2s_reciever
    wire [23:0] rxdata_l;
    wire [23:0] rxdata_r;
    wire rxdata_vld_l;
    wire rxdata_vld_r;

    i2s_recieve_top u_i2s_reciever_top (
        .i_clk_50m(clk),
        .i_rst_n(rst_n),
        .i_i2s_sdata(i2s_data),
        .o_i2s_mclk(), // Not used
        .o_i2s_bclk(i2s_bclk),
        .o_i2s_lrclk(i2s_lrclk),
        .o_i2s_rxdata_l(rxdata_l),
        .o_i2s_rxdata_r(rxdata_r),
        .o_i2s_rxdata_vld_l(rxdata_vld_l),
        .o_i2s_rxdata_vld_r(rxdata_vld_r)
    );

    wire [15:0] b16_data;
    wire b16_data_vld;

    // Convert 24-bit to 16-bit (pick one side of the channel based on LR)
    wire [23:0] selected_channel;
    wire selected_channel_vld;
    assign selected_channel = (LR == 1'b0) ? rxdata_l : rxdata_r;
    assign selected_channel_vld = (LR == 1'b0) ? rxdata_vld_l : rxdata_vld_r;
    from_24bit_to_16bit u_24bit_to_b16it (
        .rst_n(rst_n),
        .clk(i2s_bclk),
        .data_vld_in(selected_channel_vld),
        .data_in(selected_channel),
        .data_vld_out(b16_data_vld),
        .data_out(b16_data)
    );

    wire [15:0] out_data;
    wire out_data_vld;
    // FIR Bandpass Filter
    fir_bandpass u_fir_bandpass_filter (
        .clk(i2s_bclk),
        .rst_n(rst_n),
        .en(b16_data_vld),
        .xin(b16_data),
        .yout(out_data),
        .yout_valid(out_data_vld)
    );

    // i2s_transmit
    i2s_transmit_top u_i2s_transmit_top (
        .i_clk_50m(clk),
        .i_rst_n(rst_n),
        .i_i2s_txdata_l(out_data),
        .i_i2s_txdata_r(out_data), // Send same data to both channels
        .i_i2s_txdata_vld(out_data_vld),
        .o_i2s_sdata(out_i2s_data),
        .o_i2s_mclk(), // Not used
        .o_i2s_bclk(out_i2s_bclk),
        .o_i2s_lrclk(out_i2s_lrclk),
        .o_i2s_tx_ready() // Not used
    );


endmodule